package com.gl.glbooks.repository;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.gl.glbooks.vos.Comentario;
import com.gl.glbooks.vos.Ejemplar;
import com.gl.glbooks.vos.Libro;

@Repository
public class JpaProjectRepository<T> implements ProjectRepository<T> {
	
	@PersistenceContext
	protected EntityManager em;

	public T save(T object) {
		T merge = null;
		try {
			merge = em.merge(object);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return merge;
	}
 
	public T find(Class clase, Long id) {
		T object = (T) em.find(clase, id);
		return object;
	}
 
	public T find(Class clase, String atributo, String parametro) {
				
		T objeto = null;
		try {

			Query query = em.createQuery("FROM " + clase.getSimpleName()
					+ " as objeto WHERE objeto." + atributo + " = :param");
			query.setParameter("param", parametro);
			return objeto = (T) query.getSingleResult();

		} catch (Exception e) {
			return null;
		}
	}

	public List<T> getList(Class clase) {
		Query query = null;
		try {
			query = em.createQuery("FROM " + clase.getSimpleName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}
	
	public List<T> getListCondicional(Class clase,String atributo, Object referencia) {
		Query query = null;
		try {
			System.out.println("atributo"+atributo + "- Objeto:"+referencia);
			query = em.createQuery("FROM " + clase.getSimpleName()
					+ " as objeto WHERE objeto." + atributo + " = :param");
			query.setParameter("param", referencia);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}
	
	public List<T> getListCondicionalExclude(Class clase,String atributo, Object referencia) {
		Query query = null;
		try {
			System.out.println("atributo"+atributo + "- Objeto:"+referencia);
			query = em.createQuery("FROM " + clase.getSimpleName()
					+ " as objeto WHERE objeto." + atributo + " <> :param");
			query.setParameter("param", referencia);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}

	public T find(Class clase, String atributo, Object referencia) {
		T object = null;
		Query query = em.createQuery("FROM " + clase.getSimpleName()
				+ " as objeto WHERE objeto." + atributo + " = :param");
		query.setParameter("param", referencia);
		object = (T) query.getSingleResult();

		return object;
	}
	
	public List<T> getListBusqueda(Class clase,String atributo, String dato) {
		Query query = null;
		try {
			query = em.createQuery
			("SELECT obj FROM " + clase.getSimpleName()+ " obj WHERE obj."+atributo+" = :param");
			query.setParameter("param", dato);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}

	public void delete(T object) {
		this.save(object);
	}

	@Override
	public List<T> findBetweenDates(Class clase, String atributo, Date from, Date to) {
		Query query = null;
		try {
			query = em.createQuery("FROM " + clase.getSimpleName()
					+ " as objeto WHERE objeto." + atributo + " >= :from and "
					+ "objeto." + atributo + " <= :to ");
			query.setParameter("from", from);
			query.setParameter("to", to);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}
	
	@Override
	public List<Comentario> getListComentariosNovedosos(Class clase, Integer cantidad) {
		Query query = null;
		try {
			
			query = em.createQuery("FROM Comentario ORDER BY fecha DESC");
			query.setMaxResults(5);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}
	
	@Override
	public List<Libro> getListLibrosNovedosos(Class clase, Integer cantidad) {
		Query query = null;
		try {
			
			query = em.createQuery("FROM Libro ORDER BY fechaAlta DESC");
			query.setMaxResults(5);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}

	
	@Override
	public List<T> getListSinBaja(Class clase,String atributo) {
		Query query = null;
		try {
			query = em.createQuery("FROM " + clase.getSimpleName()
					+ " as objeto WHERE objeto." + atributo + " IS NULL");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query.getResultList();
	}
}
